package cron;

import api.FetchAccountCheckList;
import api.FetchProxyIp;
import api.UpdateAccountCheckResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import core.UpdatePassword;
import dao.AccountInfo;
import dao.ProxyConfig;
import dao.Result;
import main.MyStart;
import utils.LoggerUtile;

import java.util.HashMap;
import java.util.Map;



public class CheckAccountTask {

    long startTime ;
    int retryCount ;
    int reportRetryCount =0 ;
    int proxyRetryCount ;
    int proxyMaxRetry ;
    String  data;

    ProxyConfig proxyConfig;


    AccountInfo accountInfo = new AccountInfo();
    String[] errorMessages = {
            "Proxy connection timed out",
            "Socks5 proxy rejected connection",
            "Socks5 Authentication failed",
            "timeout of 30000ms exceeded",
            "read ECONNRESET",
            "connect ECONNREFUSED",
            "Read timed out",
            "Host unreachable",
            "Malformed reply from SOCKS"
    };

    LoggerUtile logger;

    public void checkAccountTask() {
        logger = LoggerUtile.getLogger("garenaJava-account-check");
        this.startTime = System.currentTimeMillis();
        this.retryCount=0;
        this.proxyRetryCount=0;
        this.proxyMaxRetry=10;
        this.proxyConfig = new ProxyConfig();
        try {
            // 实现checkAccountTask的逻辑
            Map<String, Object> body = new HashMap<>();
            body.put("pageNum", 1);
            body.put("pageSize", 1);
            String s = JSON.toJSONString(body);
            String response = null;
            response =new FetchAccountCheckList().fetchAccountCheckList(MyStart.addr_gamecenter,s);
            logger.info("请求账号检查任务列表结果"+response);
            data = response;
            JSONObject datas = (JSONObject) JSONObject.parse(response);
            JSONObject data1 = datas.getJSONObject("data");
            if (data1 == null || data1.get("result")==null){ //回看历史数据，返回的result基本都是空，所以走不到下面流程
                return;
            }
            JSONArray result = (JSONArray) JSONArray.parse(JSON.toJSONString(data1.get("result")));
            if(result.size() == 0){
                return;
            }
            JSONObject res = result.getJSONObject(0);
            logger.info("账号:" + res.getString("account"));
            if(res.getString("account").startsWith("\"") && res.getString("account").endsWith("\"")){
                accountInfo.account = res.getString("account").substring(1,res.getString("account").length()-1);
            }else {
                accountInfo.account =res.getString("account");
            }
            if(res.getString("password").startsWith("\"") && res.getString("password").endsWith("\"")){
                accountInfo.password = res.getString("password").substring(1,res.getString("password").length()-1);
            }else {
                accountInfo.password =res.getString("password");
            }
            if(res.getString("accountKey").startsWith("\"") && res.getString("accountKey").endsWith("\"")){
                accountInfo.garenaKey = res.getString("accountKey").substring(1,res.getString("accountKey").length()-1);
            }else {
                accountInfo.garenaKey =res.getString("accountKey");
            }

            accountInfo.haoId =res.getString("accountSeatId");


            // if (env.equals("prod")){
            fetchProxy(null);
            //  }else {
            //      checkAccount();
            //  }
        }catch (Exception e){
            logger.error("开始检查任务处理异常" + e.getMessage());
            if(e.getMessage().contains("Connection timed out")){
                logger.info("检查服务超时！重新获取Nacos地址！");
                MyStart.createNacosConnect();
            }
        }

    }

    private void fetchProxy(String dsip) {
        Map<String, Object> body = new HashMap<>();
        body.put("proxyType", 1);
        body.put("disableIp", (dsip!=null ? dsip : null));
        String s = JSON.toJSONString(body);
        String response = null;
        try {
            response = FetchProxyIp.fetchProxyIp(MyStart.addr_security,s);
            logger.info("代理查询结果"+response);
            JSONObject jsonObject = JSONObject.parseObject(response);
            proxyConfig.setIp(jsonObject.getJSONObject("data").getString("ip"));
            proxyConfig.setPort(Integer.valueOf(jsonObject.getJSONObject("data").getString("port")));
            checkAccount();
        }catch (Exception e){
            StackTraceElement stackTraceElement= e.getStackTrace()[0];
            this.proxyRetryCount++;
            // 代理查询请求异常重试
            if (this.proxyRetryCount < this.proxyMaxRetry) {
                logger.error("代理IP查询失败,稍后重试" + stackTraceElement.getLineNumber() );
                fetchProxy(null);
                return;
            }
            handleCompleted(new Result(-1,"代理IP查询异常",e.getMessage()));
        }


    }

    private void checkAccount() {
        try {
            long endTime = System.currentTimeMillis();
            this.retryCount++;
            logger.info("开始第"+this.retryCount+"次检查任务" + data);
            logger.info("检查任务前：" + accountInfo.getAccount() +" 密码：" +accountInfo.getPassword());

            UpdatePassword updatePassword = new UpdatePassword();
            Result result = updatePassword.start(accountInfo,proxyConfig,1, MyStart.addr_security, MyStart.addr_gamecenter);
            logger.info("第" + this.retryCount + "次检查任务完成" + JSON.toJSONString(result));
            logger.info("检查耗时" + (endTime - startTime));
            JSONObject Jresult = (JSONObject) JSONObject.parse(JSON.toJSONString(result));
            int code = (int) Jresult.get("code");
            if (code == -1 && this.retryCount < 5) {
                String msg = Jresult.getString("msg");
                if(msg!=null && msg.contains("需要验证")){
                    logger.info("代理失效重新获取代理：" + proxyConfig.getIp());
                    retryCount++;
                    fetchProxy(proxyConfig.getIp());
                    return;
                }
                String error = (String) Jresult.get("data");
                if (error != null) {
                    for (String errorMessage : errorMessages) {
                        if(error.contains(errorMessage)){
                            logger.info("代理IP异常" + proxyConfig.getIp());
                            fetchProxy(proxyConfig.getIp());
                            return;
                        }
                    }
                }
                logger.info("连接异常重试 次数：" + retryCount);
                fetchProxy(proxyConfig.getIp());
                return;
            }
            String msg = (String) Jresult.get("msg");
            handleCompleted(new Result(code,msg,result));

        }catch (Exception e){
            logger.error("检查任务处理异常:"+e.getMessage());
        }

    }

    public void handleCompleted(Result result) {
        try {
            /*
            java.lang.String cannot be cast to com.alibaba.fastjson.JSONObject
             */


            int code =  result.getCode();


            Map<String, Object> formData = new HashMap<>();
            formData.put("accountSeatId", accountInfo.getHaoId());
            formData.put("passwordCheckStatus", 4);

            if (code == -1) {
                formData.put("passwordCheckStatus", 4); // 网络异常未知
            }
            if (code >= 20 && code < 30) {
                formData.put("passwordCheckStatus", 3); // 账号无效/密码未知/key未知
            }
            if (code >= 30 && code < 40) {
                formData.put("passwordCheckStatus", 6); // 账号有效/密码无效/key未知
            }
            if (code >= 60 && code < 70) {
                formData.put("passwordCheckStatus", 7); // 账号有效/密码有效/key无效
            }
            if (code == 0) {
                formData.put("passwordCheckStatus", 5); // 账号/密码/key都有效
            }
            String s = JSON.toJSONString(formData);
            String res = UpdateAccountCheckResult.updateAccountCheckResult(MyStart.addr_gamecenter,s);
            logger.info("更新检查结果完成" + res);
            logger.info("检查任务全程耗时"+ (System.currentTimeMillis() - startTime));
        } catch (Exception error) {
            StackTraceElement stackTraceElement= error.getStackTrace()[0];
            // 接口异常 一分钟后重试
            logger.error("更新检查结果请求异常,请稍后再试试" + stackTraceElement.getLineNumber());
            reportRetryCount = reportRetryCount + 1;
            if (this.reportRetryCount < 2) {
                handleCompleted(result);
            }
        }
    }


}
